package elijah.base.binding;

import android.text.TextUtils;
import android.util.Pair;
import android.view.View;
import android.widget.TextView;

import androidx.viewbinding.ViewBinding;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Locale;

import elijah.base.utils.CommonUtils;

public abstract class DataBinding<T, V extends ViewBinding> {
    public static final boolean enable = true;
    private final HashMap<String, Pair<Object, Field>> pairMap;
    private final HashMap<String, String> formatMap;


    public DataBinding(V viewBinding, T entity) {
        if (!enable) {
            return;
        }
        Field[] viewFields = viewBinding.getClass().getDeclaredFields();
        pairMap = new HashMap<>(viewFields.length);
        HashMap<String, Object> viewMap = new HashMap<>(viewFields.length);
        for (Field field : viewFields) {
            field.setAccessible(true);
            try {
                Object o = field.get(viewBinding);
                if (o instanceof TextView || o instanceof TextBindable) {
                    viewMap.put(field.getName(), o);
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }

        Field[] beanFields = entity.getClass().getDeclaredFields();
        formatMap = new HashMap<>(beanFields.length);
        for (Field field : beanFields) {
            field.setAccessible(true);
            String fieldName = field.getName();

            BindingFormat annotation = field.getAnnotation(BindingFormat.class);
            if (annotation != null) {
                if (!annotation.bindEnable()) {
                    continue;
                }
                if (!TextUtils.isEmpty(annotation.name())) {
                    fieldName = annotation.name();
                }
                if (!TextUtils.isEmpty(annotation.format())) {
                    formatMap.put(fieldName, annotation.format());
                }
            }

            Object view = viewMap.get(fieldName);
            if (view != null) {
                pairMap.put(fieldName, Pair.create(view, field));
            }


        }


    }

    public void bindData(T value) {
        if (!enable) {
            return;
        }
        for (String name : pairMap.keySet()) {
            Pair<Object, Field> pair = pairMap.get(name);
            if (pair == null) {
                continue;
            }
            try {
                String format = formatMap.get(name);
                Object filed = value != null ? pair.second.get(value) : null;
                if (pair.first instanceof TextView) {
                    ((TextView) pair.first).setText(value == null || filed == null ? CommonUtils.EMPTY : !TextUtils.isEmpty(format) ? String.format(Locale.getDefault(), format, filed) : filed.toString());
                } else if (pair.first instanceof TextBindable) {
                    ((TextBindable) pair.first).setText(value == null || filed == null ? CommonUtils.EMPTY : !TextUtils.isEmpty(format) ? String.format(Locale.getDefault(), format, filed) : filed.toString());
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }


}